package com.core.cloudbusiness.system.login.controller;

import com.core.cloudbusiness.system.device.service.UserDeviceService;
import com.core.cloudbusiness.system.login.service.CloudSystemLoginService;
import com.core.cloudbusiness.system.login.service.Impl.CloudSystemLoginServiceImpl;
import com.core.cloudcommon.CommonCustomException;
import com.core.cloudcommon.CommonResult;
import com.core.cloudcommon.enums.CloudSystemLoginResultCode;
import com.core.cloudcommon.security.JwtTokenUtil;
import com.core.cloudcommon.security.LoginSecurityManager;
import com.core.cloundbusinessapi.system.device.dto.UserDeviceDTO;
import com.core.cloundbusinessapi.system.login.dto.CloudSystemLoginDTO;

import com.core.cloundbusinessapi.system.login.vo.CloudSystemLoginVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @author =====Lqj=====
 * @className CloudSystemLoginController
 * @description
 * @create 2024/11/16 13:08
 **/
@RestController
@RequestMapping("/cloud/sys")
public class CloudSystemLoginController {

    @Autowired
    private CloudSystemLoginService cloudSystemLoginService;

    @Autowired
    private LoginSecurityManager loginSecurityManager;

    @Autowired
    private UserDeviceService userDeviceService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;


    /**
     * 登陆
     *
     * @return
     */
    @PostMapping("/login")
    public CommonResult<CloudSystemLoginDTO> login(@Validated @RequestBody CloudSystemLoginVO cloudSystemLoginVO,
                                                   HttpServletRequest request) {
        // 获取客户端IP
        String clientIp = loginSecurityManager.getClientIp(request);

        // IP锁定检查
        //loginSecurityManager.checkIpLock(clientIp);

        // 接口限流检查：每分钟最多5次登录尝试
        if (!loginSecurityManager.checkRateLimit(clientIp, "login", 5, 60)) {
            loginSecurityManager.recordIpFail(clientIp);
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200021.getCode(),
                                          CloudSystemLoginResultCode.CODE200021.getMsg());
        }

        try {
            CloudSystemLoginDTO result = cloudSystemLoginService.login(cloudSystemLoginVO, request);
            return CommonResult.OK(result);
        } catch (CommonCustomException e) {
            // 登录失败时记录IP失败
            loginSecurityManager.recordIpFail(clientIp);
            throw e;
        }
    }


    /**
     * 退出
     *
     * @return
     */
    @GetMapping("/exit/{token}")
    public CommonResult<Void> exit(@PathVariable("token") String token, HttpServletRequest request) {
        cloudSystemLoginService.exit(token, request);
        return CommonResult.OK();
    }


    /**
     * 发送短信验证码
     *
     * @return
     */
    @PostMapping("/sendSms")
    public CommonResult<Boolean> sendSms(@Validated @RequestBody CloudSystemLoginVO cloudSystemLoginVO,
                                        HttpServletRequest request) {
        // 获取客户端IP
        String clientIp = loginSecurityManager.getClientIp(request);

        // 接口限流检查：每分钟最多3次发送验证码
        if (!loginSecurityManager.checkRateLimit(clientIp, "sendSms", 3, 60)) {
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200021.getCode(),
                                          "发送验证码过于频繁，请稍后重试");
        }

        // 调用带IP参数的发送方法
        boolean result = ((CloudSystemLoginServiceImpl) cloudSystemLoginService).sendSms(cloudSystemLoginVO.getPhone(), clientIp);
        return CommonResult.OK(result);
    }

    /**
     * 刷新Token
     *
     * @param request HTTP请求
     * @return 新的登录信息
     */
    @PostMapping("/refreshToken")
    public CommonResult<CloudSystemLoginDTO> refreshToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null || token.trim().isEmpty()) {
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200022.getCode(),
                                          "Token不能为空");
        }

        return CommonResult.OK(cloudSystemLoginService.refreshToken(token));
    }

    /**
     * 踢出其他设备
     *
     * @param request HTTP请求
     * @return 操作结果
     */
    @PostMapping("/kickOutOtherDevices")
    public CommonResult<Boolean> kickOutOtherDevices(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null || token.trim().isEmpty()) {
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200022.getCode(),
                                          "Token不能为空");
        }

        return CommonResult.OK(cloudSystemLoginService.kickOutOtherDevices(token));
    }

    /**
     * 获取用户设备列表
     *
     * @param request HTTP请求
     * @return 设备列表
     */
    @GetMapping("/devices")
    public CommonResult<List<UserDeviceDTO>> getUserDevices(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token == null || token.trim().isEmpty()) {
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200022.getCode(),
                                          "Token不能为空");
        }

        // 从token获取用户ID（这里需要实现获取当前用户的方法）
        // 简化处理，假设有获取当前用户的方法
        Long userId = getCurrentUserId(request);
        List<UserDeviceDTO> devices = userDeviceService.getUserDevices(userId);

        // 标记当前设备
        for (UserDeviceDTO device : devices) {
            if (token.equals(device.getToken())) {
                device.setIsCurrent(true);
                break;
            }
        }

        return CommonResult.OK(devices);
    }

    /**
     * 获取在线设备列表
     *
     * @param request HTTP请求
     * @return 在线设备列表
     */
    @GetMapping("/devices/online")
    public CommonResult<List<UserDeviceDTO>> getOnlineDevices(HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        List<UserDeviceDTO> devices = userDeviceService.getOnlineDevices(userId);
        return CommonResult.OK(devices);
    }

    /**
     * 踢出指定设备
     *
     * @param deviceId 设备ID
     * @param request HTTP请求
     * @return 操作结果
     */
    @PostMapping("/devices/{deviceId}/kickOut")
    public CommonResult<Boolean> kickOutDevice(@PathVariable("deviceId") String deviceId,
                                              HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        boolean result = userDeviceService.kickOutDevice(userId, deviceId);
        return CommonResult.OK(result);
    }

    /**
     * 设备重命名
     *
     * @param deviceId 设备ID
     * @param newName 新名称
     * @param request HTTP请求
     * @return 操作结果
     */
    @PostMapping("/devices/{deviceId}/rename")
    public CommonResult<Boolean> renameDevice(@PathVariable("deviceId") String deviceId,
                                             @RequestParam("newName") String newName,
                                             HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        boolean result = userDeviceService.renameDevice(userId, deviceId, newName);
        return CommonResult.OK(result);
    }

    /**
     * 设置设备为可信
     *
     * @param deviceId 设备ID
     * @param request HTTP请求
     * @return 操作结果
     */
    @PostMapping("/devices/{deviceId}/trust")
    public CommonResult<Boolean> trustDevice(@PathVariable("deviceId") String deviceId,
                                            HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        boolean result = userDeviceService.trustDevice(userId, deviceId);
        return CommonResult.OK(result);
    }

    /**
     * 取消设备可信状态
     *
     * @param deviceId 设备ID
     * @param request HTTP请求
     * @return 操作结果
     */
    @PostMapping("/devices/{deviceId}/untrust")
    public CommonResult<Boolean> untrustDevice(@PathVariable("deviceId") String deviceId,
                                              HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        boolean result = userDeviceService.untrustDevice(userId, deviceId);
        return CommonResult.OK(result);
    }

    /**
     * 获取设备统计信息
     *
     * @param request HTTP请求
     * @return 统计信息
     */
    @GetMapping("/devices/statistics")
    public CommonResult<Map<String, Object>> getDeviceStatistics(HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        Map<String, Object> statistics = userDeviceService.getDeviceStatistics(userId);
        return CommonResult.OK(statistics);
    }

    /**
     * 检测异常设备
     *
     * @param request HTTP请求
     * @return 异常设备列表
     */
    @GetMapping("/devices/abnormal")
    public CommonResult<List<UserDeviceDTO>> detectAbnormalDevices(HttpServletRequest request) {
        Long userId = getCurrentUserId(request);
        List<UserDeviceDTO> abnormalDevices = userDeviceService.detectAbnormalDevices(userId);
        return CommonResult.OK(abnormalDevices);
    }

    /**
     * 获取当前用户ID（辅助方法）
     * 从JWT token中获取用户ID
     */
    private Long getCurrentUserId(HttpServletRequest request) {
        try {
            String token = request.getHeader("token");
            if (token == null || token.trim().isEmpty()) {
                throw new CommonCustomException(CloudSystemLoginResultCode.CODE200022.getCode(),
                                              "Token不能为空");
            }

            // 从JWT token中获取用户ID
            return jwtTokenUtil.getUserIdFromToken(token);
        } catch (Exception e) {
            throw new CommonCustomException(CloudSystemLoginResultCode.CODE200022.getCode(),
                                          "获取用户信息失败");
        }
    }
}
